/*!
 * \file build_sym_table_visitor.h
 *
 * \brief Declarations of the BuildSymTableVisitor that traverses the AST
 *
 * \date Started: 6/8/2010
 * \date Last Modified: 6/8/2010
 * \authors Alan LaMielle Nicholas Jeanette
 *
 * Copyright (c) 2010, Colorado State University <br>
 * All rights reserved. <br>
 * See ../../COPYING for details. <br>
 */

#ifndef BUILD_SYM_TABLE_VISITOR_H_
#define BUILD_SYM_TABLE_VISITOR_H_

#include <iegenlib/iegenlib.h>

#include <map>
#include <list>
#include <set>
#include <utility>

namespace iegenlib{

/*!
 * \class BuildSymTableVisitor
 * \brief Visitor class that is used to build the SparseConstraints SymbolTable
 *
 * This class uses the DepthFirstVisitorAdapter to make a traversal of the AST
 * so the SparseConstraints symbol table can be built and accessed
 */
class BuildSymTableVisitor: public DepthFirstVisitorAdapter{
public:

   /*!
   * Build Symbol Table Visitor Constructor
   *
   * The constructor will set up all parameters that are needed to construct the
   * the symbol table.
   * @param set of strings that represent the collection of symbolic constants that
   * will be added to the symbol table
   */

   BuildSymTableVisitor(set<string>);


   /*!
   * getSymTable
   *
   * This is were the symbol table is actually constructed when called for the
   * first time. If the call is not the first then it returns the symbol table
   * that has already been created.
   * @return a pointer to the symbol table
   */
   SymbolTable* getSymTable();

   /*!
   * Used for general tasks to be done going into every visited node
   * @param node node to do tasks on
   */
   inline void defaultIn(Node* node){}

   /*!
   * Used for general tasks to be done going out of every visited node
   * @param node node to do tasks on
   */
   inline void defaultOut(Node* node){}

   /*!
   * Function called by the VarTupleCase method for the VarTuple node this is
   * where the list of varTuples gets built
   * @param node node that calls the case method
   */
   void VarTupleCase(VarTuple* node);

   /*!
   * Function called by the FuncExpCase method for the FuncExp node
   * this is where FunCounter gets incremented
   * @param node node that calls the case method
   */
   void FuncExpOut(FuncExp* node);

   /*!
   * We check if the exp was declared as a VarTup if not we then add it to the
   * existentials list
   * @param pointer to the next VarExp node in the ast
   */
   void VarExpOut(VarExp* node);

   /*!
   * This is leaving the root node in this function all of the tree has been
   * traversed and all lists/sets have been constructed and filled. All that is
   * needed is creation of unique names and function calls the method to do so.
   * @param pointer to the PresSet node in the ast (this is the root node)
   */
   void PresSetIn(PresSet* node);

   /*!
   * This is leaving the root node in this function all of the tree has been
   * traversed and all lists/sets have been constructed and filled. All that is
   * needed is creation of unique names and function calls the method to do so.
   * @param pointer to the PresRelation node in the ast (this is the root node)
   */
   void PresRelationIn(PresRelation* node);

   void ConjunctionOut(Conjunction* node);

   /*!
   * A getter for the tuple var list so we have access to the entirety of all
   * string for tupvars includes duplicates
   * @return the list of unaltered tuple vars represented as strings
   */
   list<std::string> getTupleVarList();

   /*!
   * getter for the inArity
   * @return int of the in Arity
   */
   inline int getInArity(){return inArity;}

   /*!
   * getter for the outArity
   * @return int of the out Arity
   */
   inline int getOutArity(){return outArity;}

   inline list<TupleType> getTuples() { return list<TupleType>(TupleList.begin(), TupleList.end()); }

   inline set<SREquality> getEqualities() const {return equalities;}

private:

   /*!
   * In this function we actually build a symbol table. This is called from the
   * root node of the ast we are using. In this method we deal with the
   * duplicate tuple variables by giving them a unique name. We also create the
   * equalities that are needed for these.
   */
   void buildSymTable();

   /*!
   * A function that checks to see if the name exists in the set of existentals
   * or the set of symbolics or if this is already in the list of tuples this
   * function is used to make sure that our new name is in fact unique to the
   * set
   * @param the string representation of the new "unique" name
   * @return bool if the string is found in the list returns true otherwise
   * returns true.
   */
   bool alreadyInSets(std::string newName);

   void makeEqualities();

   ///a list of strings holding the tuplevars
   list<std::string> tupvarlist;

   ///This is a pointer to our symbol table
   SymbolTable* ST;

   ///a counter used to count the number of function calls
   int FunCounter;

   ///a set of symbolics
   set<std::string> syms;

   /*!
   * this is a map that holds each of the unique tuple vars prior to renaming
   * duplicate variables. the second value is a counter to aid in the renaming
   * of variables that must be renamed.
   */
   map<std::string, int> tupvarMap;

   ///a set of the existential
   set<std::string> exists;

   /// a map of original string names to new unique names
   map<std::string, list<std::string> > mNumToDups;

   ///boolean that states if we have finished the in arity
   bool iArity;

   ///integer count of the in arity
   int inArity;

   ///integer count of the out arity
   int outArity;

   vector<TupleType> TupleList;

   set<string> currentNames;

   set<SREquality> equalities;

   bool firstConj;
};

}//end namespace iegenlib

#endif /* BUILD_SYM_TABLE_VISITOR_H_ */
